﻿using Ldt.DataEngine.DataFlowParse.Model;
using LdtDataEngin.ModuleDetail.BaseModule;
using LdtDataEngin.ModuleDetail.BaseModule.UIEExtract;
using LdtDataEngin.ModuleDetail.RegCommon;
using LdtJudge.DataEngine.Common;
using LdtJudge.DataEngine.Data;
using LdtJudge.DataEngine.DataBaseStores;
using LdtJudge.DataEngine.Model.DataModel.CommonManageModel;
using LdtJudge.DataEngine.Model.DataModel.ElementNode;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace LdtDataEngin.ModuleDetail.AnalysisModule.CaseExtract
{
    /// <summary>
    /// 案件要素机器学习组件
    /// </summary>
    public class CaseElementMachLearnAssemble
    {
        #region 基础信息加载
        //上下文数据
        public DataContext _dataContext;

        //UIE提取模型
        private readonly UIEServiceProxy uieService = new UIEServiceProxy();

        SqlCmmCommon sqlCmm = new SqlCmmCommon("LdtCommonManage");
        #endregion

        /// <summary>
        /// 通过机器学习提取案件要素节点数据
        /// </summary>
        /// <param name="originalText">原文</param>
        /// <param name="parentId">父级节点ID</param>
        /// <param name="nodePath">节点xpath</param>
        /// <param name="moduleName">模块名称</param>
        /// <returns></returns>
        public List<ElementNodeModel> MachLearnExtract(string originalText,string parentId,string nodePath,string moduleName)
        {
            sqlCmm.DicTabel = _dataContext.DataLayerAns.dicTable;
            List<ElementNodeModel> result = new List<ElementNodeModel>();
            UieModelHandleClass uieModelHandle = new UieModelHandleClass();
            string modelCode = "wxjsz_qsyjs";
            string xmlConfig = string.Empty;
            string uieConfig = GetUieConfig(moduleName);
            if(!string.IsNullOrWhiteSpace(uieConfig))
                xmlConfig= HttpHelp.EnDataBase64(uieConfig);
            var param = new
            {
                modelCode = modelCode,
                content = originalText,
                xmlConfig = xmlConfig
            };
            _dataContext.InteractiveShow.LogShow($"案件要素节点【{nodePath}】的原文【{originalText}】调用UIE模型提取入参：{JsonConvert.SerializeObject(param)}");
            var uieResponse = uieService.UieRecognition(modelCode, originalText, xmlConfig);
            _dataContext.InteractiveShow.LogShow($"案件要素节点【{nodePath}】调用UIE模型提取结果：{JsonConvert.SerializeObject(uieResponse)}");
            if (uieResponse.Body != null && uieResponse.Body.Any())
            {
                //将UIE模型返回数据转换为xml
                XmlDocument modelXml = uieModelHandle.UieModelToXml(uieResponse.Body, "案件信息要素中心");
                _dataContext.InteractiveShow.LogShow($"案件要素节点【{nodePath}】UIE模型提取数据转换xml：{modelXml.OuterXml}");
                //将xml转换为ElementNodeModel数据集合
                string executeCode = _dataContext.DataLayerSys.GetConfigModel(moduleName).ExecuteCode;
                var elementNodeModels = XmlToElementNodeModel(modelXml, parentId, originalText, executeCode);
                if (elementNodeModels != null && elementNodeModels.Any())
                {
                    var nodeList = elementNodeModels.Where(x => x.Path.Contains(nodePath)).ToList();
                    if (nodeList != null && nodeList.Any())
                    {
                        foreach (var nodeItem in nodeList.Where(x => x.Path == nodePath))
                        {
                            nodeItem.ParentId = parentId;
                        }
                        result = nodeList;
                    }
                }
            }
            return result;
        }


        /// <summary>
        /// 获取UIE模型提取配置
        /// </summary>
        /// <param name="mouldeName">模块名称</param>
        /// <returns></returns>
        private string GetUieConfig(string mouldeName)
        {
            string configContent = string.Empty;
            var configModel = _dataContext.DataLayerSys.GetConfigModel(mouldeName);
            if(configModel!=null)
            {
                List<ConfigModel> configDetailList = configModel.ConfigDetail;
                if(configDetailList!=null && configDetailList.Any())
                {
                    ConfigModel configDetail = configDetailList.FirstOrDefault(a => a.Code.ToLower() == "elementmachlearn");
                    if (configDetail != null)
                        configContent = configDetail.ConfigContent;
                }
            }
            return configContent;
        }

        /// <summary>
        /// 将XmlDocument转换为ElementNodeModel
        ///  
        /// </summary>
        /// <param name="xmlDocument">xmlDocument</param>
        /// <param name="parentId">父级ID</param>
        /// <param name="orgText">原文</param>
        /// <param name="executeCode">模块执行编号</param>
        /// <returns></returns>
        private List<ElementNodeModel>XmlToElementNodeModel(XmlDocument xmlDocument, string parentId, string orgText,string executeCode)
        {
            List<ElementNodeModel> result = new List<ElementNodeModel>();
            foreach (XmlNode xmlNode in xmlDocument.ChildNodes)
            {
                NodeChangeModel(xmlNode,result, xmlNode.Name,"",orgText, executeCode);
            }
            return result;
        }

        /// <summary>
        /// 加载案件要素节点Model数据
        /// </summary>
        /// <param name="xmlNode">Xml节点</param>
        /// <param name="elementNodesList">ElementNodeModel集合</param>
        /// <param name="xpath">节点Xpath路径</param>
        /// <param name="parentId">父级ID</param>
        /// <param name="orgText">原文</param>
        private void NodeChangeModel(XmlNode xmlNode, List<ElementNodeModel> elementNodesList, string xpath, string parentId, string orgText,string executeCode)
        {
            string ccid = string.Empty;
            if (_dataContext.DataLayerAns.CaseCausesList != null && _dataContext.DataLayerAns.CaseCausesList.Any())
                ccid = _dataContext.DataLayerAns.CaseCausesList[0].CC_ID;
            ElementNodeModel elementNodeModel = new ElementNodeModel();
            elementNodeModel.Id = Snowflake.Instance().GetId().ToString();
            elementNodeModel.ParentId = parentId;
            elementNodeModel.Path = xpath;
            elementNodeModel.Name = xmlNode.Name;
            elementNodeModel.IsNode = "1";
            elementNodeModel.OrigianlTextStr = orgText;
            elementNodeModel.OriginalTextList = new List<string>();
            elementNodeModel.ParagraphName = string.Empty;
            elementNodeModel.DictionariesCode = string.Empty;
            elementNodeModel.OriginalTextList.Add(orgText);
            elementNodeModel.ExtOriginalText = orgText;
            elementNodeModel.interactiveModel = null;
            elementNodesList.Add(elementNodeModel);
            foreach (XmlAttribute attribute in xmlNode.Attributes)
            {
                var attrName = attribute.Name;
                if(attrName!="id")
                {
                    string attrPath = $"{xpath}\\{attrName}";
                    ElementNodeModel elementAttrModel = new ElementNodeModel();
                    elementAttrModel.Id = Snowflake.Instance().GetId().ToString();
                    elementAttrModel.ParentId = elementNodeModel.Id;
                    elementAttrModel.Path = attrPath;
                    elementAttrModel.IsNode = "0";
                    elementAttrModel.Name = attrName;
                    elementAttrModel.OriginalTextList = new List<string> { attribute.Value };
                    elementAttrModel.interactiveModel = null;
                    elementAttrModel.Value = attribute.Value;
                    elementAttrModel.ParagraphName = string.Empty;
                    elementAttrModel.DictionariesCode = string.Empty;
                    elementAttrModel.OrigianlTextStr = attribute.Value;
                    elementAttrModel.ExtOriginalText = attribute.Value;
                    //获取转换函数数据，如果转换函数数据存在则调用转换函数
                    var convertMode = GetConvertCode(attrPath, executeCode);
                    if (!string.IsNullOrWhiteSpace(convertMode?.CM_Code))
                    {
                        RegCommon.ConvertModeAnalysis.IConvertAnalysis convertAnalysis = ProcessCompose.GetConvertModel(Convert.ToInt32(convertMode?.CM_CMode), ccid);
                        var values = convertAnalysis.ConvertValue(convertMode, attribute.Value, _dataContext.DataLayerAns.CaseType, ccid);
                        if (values != null && values.Any())
                            elementAttrModel.Value = values[0];
                        //_dataContext.InteractiveShow.LogShow("数据转换：转换前为：" + attribute.Value + " 转换后为：" + (values.Any() ? values[0] : ""), LogMessageType.Info);

                    }
                    elementNodesList.Add(elementAttrModel);
                }
            }
            foreach (XmlNode node in xmlNode.ChildNodes)
            {
                string childNodePath = $"{elementNodeModel.Path}\\{node.Name}";
                NodeChangeModel(node, elementNodesList, childNodePath, elementNodeModel.Id, orgText, executeCode);
            }
        }

        /// <summary>
        /// 通过节点路径和模块名称获取转换函数数据
        /// </summary>
        /// <param name="nodePath">节点路径</param>
        /// <param name="moduleName">模块名称</param>
        /// <returns></returns>
        private ConvertMode GetConvertCode(string nodePath,string moduleName)
        {
            ConvertMode convertMode = sqlCmm.GetConvertModeForML(nodePath, moduleName);
            return convertMode;
        }
    }
}
